#include <string.h>
#include <stdio.h>
#include "setting.h"
#include "virtual_flash.h"
#include "comfun.h"
#include "sensor_archives.h"

sensor_archives_t  sensor_archives;
uint32_t archives_bit_map=0;
uint32_t sensor_start_addr = ARCHIVES_VALID_ADDR;

/*
*遍历flash档案  检查有效标志位  返回有效从机数量
* 返回值：1-16正确  -1错误
*/
static uint8_t get_max_valid_nums(void)
{
    uint8_t valid_nums=0;
    int i;

    for(i=0;i<SENSOR_ARCHIVE_NUMS;i++)
    {
        if(sensor_archives.sensor_infor[i].flag == SENSOR_VALID)
            valid_nums++;
    }

    if(valid_nums<=16)
        return valid_nums;
    else
        return -1;
}

//搜表前调用  将所有表设为无效
void set_all_sensor_invalid(void)
{
    int i;

    for(i=0;i<=archives_bit_map;i++)
    {
        sensor_archives.sensor_infor[i].flag = SENSOR_INVALID;
    }
}

//检查该地址是否已经存在档案中
//是 返回1  否 返回0
int is_in_sensor_archives(uint8_t aid[])
{
    int i;

    for(i=0;i<=archives_bit_map;i++)
    {
        if(0 == memcmp(aid,sensor_archives.sensor_infor[i].aid,AID_LEN))
        {
            sensor_archives.sensor_infor[i].flag = SENSOR_VALID;//此表有效
            return 1;
        }
    }

    return 0;
}

int save_new_sensor_infor(uint8_t aid[])
{
    archives_bit_map++;//指向下一个位置
    memcpy(sensor_archives.sensor_infor[archives_bit_map].aid,aid,AID_LEN);
    sensor_archives.sensor_infor[archives_bit_map].seq = seq;
    sensor_archives.sensor_infor[archives_bit_map].flag = SENSOR_VALID;

    return 1;
}

void sensor_archives_save(void)
{
    sensor_hdr_t hdr;
    uint32_t addr = sensor_start_addr + sizeof(sensor_archives_t);//起始地址+当前使用的数据长度
    BOOL new_sec = FALSE;

    //如果addr大于存储空间
    if (addr >= ARCHIVES_VALID_ADDR || (addr + sizeof(sensor_archives_t) >= ARCHIVES_VALID_ADDR))
    {
        //printf("flash start over\n");
        addr = ARCHIVES_FROM; //存储地址切换到最开始
        new_sec = TRUE;      //更新重新存储标志
    }
    //如果即将使用的存储空间超过一页
    if ((addr & FLASH_SECTOR_MASK) + sizeof(sensor_archives_t) > FLASH_SECTOR_SIZE)
    {
        //printf("over one sector\n");
        addr = (addr + FLASH_SECTOR_SIZE) & (~FLASH_SECTOR_MASK);//从下一页开始
        new_sec = TRUE;
    }
    //首次使用
    if (!(addr & FLASH_SECTOR_MASK))
    {
        new_sec = TRUE;
    }

    /* erase next sector if need a new sector */
    if (new_sec)
    {
        disk_erase(addr,FLASH_SECTOR_SIZE);
    }

    /* check memory */
    sensor_archives_t tmp;
    disk_read(addr,&tmp,sizeof (tmp));
    if(!is_all_xx((uint8_t *)&tmp, 0xFF, sizeof(tmp)))
    {
        printf("addr is %d\n",addr);
        printf("err occur\n");
        return ;
    }

    //save archives data
    if(!disk_write(addr + SENSOR_HDR_SIZE,SENSOR_INFOR_ADDR(sensor_archives),SENSOR_INFOR_SIZE))
        printf("flash write err\n");

    hdr.crc = add_crc16(SENSOR_INFOR_ADDR(sensor_archives),SENSOR_INFOR_SIZE);
    hdr.magic = SENSOR_MAGIC;
    disk_write(addr,(uint8_t *)&hdr,sizeof (hdr));//save setting crc &magic

    if (sensor_start_addr < ARCHIVES_VALID_ADDR)
    {
        memset(&hdr, 0, sizeof(hdr));
        disk_write(sensor_start_addr,(uint8_t *)&hdr,sizeof (hdr));//change last setting crc &magic
    }

    sensor_start_addr = addr;
    printf("setting_start_addr is  0x%06X!\n", addr);
    printf("setting save done \n\n");
}

//上电后执行一次
void sensor_archives_load(void)
{
    uint32_t addr;
    sensor_hdr_t hdr;

    for(addr = ARCHIVES_FROM;addr < ARCHIVES_VALID_ADDR;addr += sizeof (sensor_archives_t))
    {
        board_feed_wdg();
        //将要读取的flash地址超过一整页
        if ((addr & FLASH_SECTOR_MASK) + sizeof(sensor_archives_t) > FLASH_SECTOR_SIZE)
        {
            addr = (addr + FLASH_SECTOR_SIZE) & (~FLASH_SECTOR_MASK); //从下一页开始
        }

        if(addr >= ARCHIVES_VALID_ADDR)//下一页超出寻址范围
        {
            break;
        }

        board_feed_wdg();//读取flash时间长 防止看门狗复位

        disk_read(addr,(uint8_t *)&hdr,SENSOR_HDR_SIZE);
        if(hdr.magic != SENSOR_MAGIC)
            continue;

        disk_read(addr+SENSOR_HDR_SIZE,SENSOR_INFOR_ADDR(sensor_archives),SENSOR_INFOR_SIZE);
        if (hdr.crc != add_crc16(SENSOR_INFOR_ADDR(sensor_archives), SENSOR_INFOR_SIZE))
            continue;//crc校验不过  继续循环

        //找到正确数据
        sensor_start_addr = addr;
        printf("sensor archives addr: 0x%06X!\r\n", addr);

        int i;
        for(i=0;i<SENSOR_ARCHIVE_NUMS;i++)
        {
            if(!is_all_xx(sensor_archives.sensor_infor[i].aid,0x00,AID_LEN) && \
                !is_data_all_xx(sensor_archives.sensor_infor[i].aid,0xff,AID_LEN) && \
                    sensor_archives.sensor_infor[i].flag == SENSOR_VALID)
            {
                archives_bit_map++;
            }
        }
        return;
    }

    archives_bit_map=0;
    printf("sensor archives not found!!\n");
}

void sensor_archives_show(uint8_t sensor_map)
{
    log_d("sensor_infor[%d].aid is %d\n",sensor_map,get_le_val(sensor_archives.sensor_infor[sensor_map].aid,AID_LEN));
    log_d("sensor_infor[%d].seq is %d\n",sensor_map,sensor_archives.sensor_infor[sensor_map].seq);
    log_d("sensor_infor[%d].flag is %d\n",sensor_map,sensor_archives.sensor_infor[sensor_map].flag);
}

